home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / host / Host_Next.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-05  |  5.9 KB  |  274 lines

  1. /* 
  2.  * Host_Next.c --
  3.  *
  4.  *    Source code for the Host_Next library procedure.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /user6/jhh/hosttest/RCS/Host_Next.c,v 1.2 92/05/29 16:30:15 voelker Exp Locker: jhh $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <stdio.h>
  21. #include <sprite.h>
  22. #include <ctype.h>
  23. #include <host.h>
  24. #include <hostInt.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <arpa/inet.h>
  28. #include <netinet/in.h>
  29.  
  30. static ReturnStatus GetInterfaces();
  31. static Net_EtherAddress emptyEtherAddr;
  32. static Net_FDDIAddress  emptyFDDIAddr;
  33.  
  34.  
  35.  
  36. /*
  37.  *-----------------------------------------------------------------------
  38.  *
  39.  * Host_Next --
  40.  *
  41.  *    Read the next line from the host file and break it into the
  42.  *    appropriate fields of the structure.
  43.  *
  44.  * Results:
  45.  *    The return value is a pointer to a Host_Entry structure
  46.  *    containing the information from the next line of the file.
  47.  *    This is a statically-allocated structure, which will only
  48.  *    retain its value up to the next call to this procedure.
  49.  *    If the end of the file is reached, or an error occurs, NULL
  50.  *    is returned.
  51.  *
  52.  * Side Effects:
  53.  *    The position in the file advances.
  54.  *
  55.  *-----------------------------------------------------------------------
  56.  */
  57. Host_Entry *
  58. Host_Next()
  59. {
  60. #define BUFFER_SIZE 512
  61. #define MAX_NAMES 20
  62.  
  63.     static Host_Entry    entry;
  64.     static char          hostBuffer[BUFFER_SIZE];
  65.     static char          interBuffer[BUFFER_SIZE];
  66.     static char *    aliases[MAX_NAMES+1];
  67.     register char *    p;
  68.     int            numAliases;
  69.     int              c;
  70.     int                 i;
  71.     register int        result;
  72.     char        *token;
  73.     int            offset;
  74.     Boolean         backup = FALSE;
  75.     Boolean        foundOne;
  76.     Net_AddressType     currentType;
  77.  
  78.     if (hostFile == (FILE *) NULL) {
  79.     return ((Host_Entry *) NULL);
  80.     }
  81.     foundOne = FALSE;
  82.     while (!foundOne) {
  83.     if (feof(hostFile)) {
  84.         return NULL;
  85.     }
  86.     offset = ftell(hostFile);
  87.     fgets(hostBuffer, BUFFER_SIZE, hostFile);
  88.     if (strchr(hostBuffer, '\n') == NULL)  {
  89.         do {
  90.         c = getc(hostFile);
  91.         } while ((c != '\n') && (c != EOF));
  92.     }
  93.     /* 
  94.      * Skip the line if it is a comment or blank.
  95.      */
  96.     if ((hostBuffer[0] == '#') || (hostBuffer[0] == '\n')) {
  97.         continue;
  98.     }
  99.  
  100.     /*
  101.      * First get the host line, then the interface lines.
  102.      */
  103.  
  104.     /*
  105.      * <spriteID>
  106.      */
  107.  
  108.     token = strtok(hostBuffer, " \t");
  109.     if (token == NULL) {
  110.         continue;
  111.     }
  112.  
  113.     if (sscanf(token, "%d", &entry.id) != 1) {
  114.         continue;
  115.     }
  116.  
  117.     /*
  118.      * <machType>:  first parse the remainder of the line up to
  119.      * fields.
  120.      */
  121.     token = strtok(NULL, " \t");
  122.     if (token == NULL) {
  123.         continue;
  124.     }
  125.     entry.machType = token;
  126.  
  127.     /*
  128.      * <name> and <aliases>
  129.      */
  130.  
  131.     token = strtok(NULL, " \t");
  132.     if (token == NULL) {
  133.         continue;
  134.     }
  135.     entry.name = token;
  136.     numAliases = 0;
  137.     token = strtok(NULL, " \t\n");
  138.     while(token != NULL) {
  139.         if (numAliases == MAX_NAMES) {
  140.         break;
  141.         }
  142.         aliases[numAliases] = token;
  143.         numAliases++;
  144.         token = strtok(NULL, " \t\n");
  145.     }
  146.     aliases[numAliases] = (char *) NULL;
  147.     foundOne = TRUE;
  148.     }
  149.  
  150.     if (!foundOne) {
  151.     return NULL;
  152.     }
  153.     entry.aliases = aliases;
  154.     foundOne = FALSE;
  155.     /*
  156.      * Now get the interface lines.
  157.      */
  158.     for (i = 0; i < HOST_MAX_INTERFACES; i++) {
  159.     entry.nets[i].netAddr.type = NET_ADDRESS_NONE;
  160.     }
  161.     i = 0;
  162.     while (!feof(hostFile)) {
  163.     if ( i >= HOST_MAX_INTERFACES) {
  164.         break;
  165.     }
  166.     offset = ftell(hostFile);
  167.     fgets(interBuffer, BUFFER_SIZE, hostFile);
  168.     if (strchr(interBuffer, '\n') == NULL)  {
  169.         do {
  170.         c = getc(hostFile);
  171.         } while ((c != '\n') && (c != EOF));
  172.     }
  173.  
  174.     /* 
  175.      * Skip the line if it is a comment or blank.
  176.      */
  177.     if ((interBuffer[0] == '#') || (interBuffer[0] == '\n')) {
  178.         continue;
  179.     }
  180.  
  181.     token = strtok(interBuffer, " \t");
  182.     if (token == NULL) {
  183.         continue;
  184.     }
  185.     /*
  186.      * Check to see if we have found a host line.  If so, stop
  187.      * gathering interface lines. Host lines begin with a digit.
  188.      */
  189.  
  190.     if (isdigit(token[0])) {
  191.         backup = TRUE;
  192.         break;
  193.     }
  194.     /*
  195.      * Reset the entry in case the previous line was invalid, and we 
  196.      * now are reusing it's entry.
  197.      */
  198.     entry.nets[i].netAddr.type = NET_ADDRESS_NONE;
  199.     /*
  200.      * <netType> and <netAddr>
  201.      */
  202.     
  203.     if (strcmp(token, "ether") == 0) {
  204.         currentType = NET_ADDRESS_ETHER;
  205.     } else if (strcmp(token, "ultra") == 0) {
  206.         currentType = NET_ADDRESS_ULTRA;
  207.     } else if (strcmp(token, "fddi") == 0) {
  208.         currentType = NET_ADDRESS_FDDI;
  209.     } else {
  210.         continue;
  211.     }
  212.     
  213.     token = strtok(NULL, " \t\n");
  214.     if (token == NULL) {
  215.         continue;
  216.     }
  217.     entry.nets[i].netAddr.type = currentType;
  218.     result = Net_StringToAddr(token, currentType,
  219.                      &entry.nets[i].netAddr);
  220.     if (result != SUCCESS) {
  221.         continue;
  222.     }
  223.     /*
  224.      * If the address is invalid, then the entry is invalid.
  225.      */
  226.     switch (currentType) {
  227.     case NET_ADDRESS_ETHER:
  228.         if (!Net_EtherAddrCmp(emptyEtherAddr, 
  229.                   entry.nets[i].netAddr.address.ether)) {
  230.         continue;
  231.         }
  232.     case NET_ADDRESS_FDDI:
  233.         if (!Net_FDDIAddrCmp(emptyFDDIAddr,
  234.                  entry.nets[i].netAddr.address.fddi)) {
  235.         continue;
  236.         }
  237.     case NET_ADDRESS_ULTRA:
  238.     default:
  239.         break;
  240.     }
  241.     
  242.     /*
  243.      * <internetAddr>
  244.      */
  245.     
  246.     token = strtok(NULL, " \t\n");
  247.     if (token == NULL) {
  248.         continue;
  249.     }
  250.     if (token[0] == '*') {
  251.         /*
  252.          * Empty internet address.
  253.          */
  254.         entry.nets[i].inetAddr = 0;
  255.     } else {
  256.         entry.nets[i].inetAddr = Net_StringToInetAddr(token);
  257.     }
  258.     /*
  259.      * Only go on to the next entry if we have successfully parsed
  260.      * a valid one.
  261.      */
  262.     foundOne = TRUE;
  263.     i++;
  264.     }
  265.     if (backup) {
  266.     fseek(hostFile, offset, 0);
  267.     }
  268.     if (!foundOne) {
  269.     return NULL;
  270.     }
  271.     entry.numNets = i;
  272.     return &entry;
  273. }
  274.